package web.controllers;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.ws.rs.core.Context;

import map.beans.EmpResponseBean;
import map.beans.JqgridResponse;
import map.beans.MapToolConfigBean;
import map.beans.owf.OwfDescriptorBean;
import map.utils.WidgetDataParser;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import web.service.interfaces.MapToolConfigServiceInterface;


@Controller
@RequestMapping(value = "admin/map/tools")
public class MapToolConfigController {
	private static Logger LOGGER = LoggerFactory.getLogger(MapToolConfigController.class);
	

	@Autowired
	private MapToolConfigServiceInterface mapToolConfigService;

	public MapToolConfigController() { }
	
	
	@SuppressWarnings("unused")
	@RequestMapping(value = "/records", method = RequestMethod.GET)
	@ResponseBody
	public JqgridResponse<MapToolConfigBean> records(@RequestParam("_search") Boolean search,
			@RequestParam(value = "nd", required = false) String filters,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "rows", required = false) Integer rows,
			@RequestParam(value = "sidx", required = false) String sidx,
			@RequestParam(value = "sord", required = false) String sord) {		
	
		JqgridResponse<MapToolConfigBean> response = null;
		Pageable pageRequest = new PageRequest(page - 1, rows);

		try {
			if (sord != null) {
				Sort sort = null;
				sort = new Sort((sord.equals("asc") ? Direction.ASC : Direction.DESC), sidx);
				pageRequest = new PageRequest(page - 1, rows, sort);

			} else {
				pageRequest = new PageRequest(page - 1, rows);
			}

			List<MapToolConfigBean> mapToolDtos = mapToolConfigService.findAll();			

			response = new JqgridResponse<MapToolConfigBean>();
			response.setRows(mapToolDtos);
			response.setRecords(Integer.valueOf(mapToolDtos.size()).toString());
			response.setTotal(Integer.valueOf(1).toString());// pages total
			response.setPage(Integer.valueOf(1).toString());

		} catch (Exception ex) {
			LOGGER.error(ex.getMessage());
		}

		return response;
	}
	
	
	@RequestMapping(value = "/create", method = RequestMethod.POST)
	@ResponseBody
	public EmpResponseBean registerMapTool(@Valid @ModelAttribute(value = "MapToolConfigBean") MapToolConfigBean mapToolsConfigBean, BindingResult result) {
		mapToolsConfigBean.setId(null);
		EmpResponseBean resp = new EmpResponseBean();
		
		ValidationUtils.rejectIfEmpty(result, "name",  		 "Widget Name can not be null");
		ValidationUtils.rejectIfEmpty(result, "descr", 		 "Widget Description can not be null");
		ValidationUtils.rejectIfEmpty(result, "iconUrl", 	 "Icon URL can not be null");
		ValidationUtils.rejectIfEmpty(result, "displayName", "Display Name can not be null");
		
		
		if ( !result.hasErrors() ) {
			mapToolConfigService.save(mapToolsConfigBean);

			resp.setStatus("SUCCESS");
			resp.setResult(mapToolsConfigBean);
		} else {
			resp.setStatus("FAIL");
			resp.setResult(result.getAllErrors());
		}

		return resp;
	}
	
	
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@ResponseBody 
	public EmpResponseBean updateMapToolRegistration(
			@Valid @ModelAttribute(value = "mapToolConfigBean") MapToolConfigBean mapToolConfigBean, BindingResult result) {
		
		List<MapToolConfigBean> mapToolsDto = new ArrayList<MapToolConfigBean>();
		EmpResponseBean resp = new EmpResponseBean();
		
		ValidationUtils.rejectIfEmpty(result, "name",  		 "Widget Name can not be null");
		ValidationUtils.rejectIfEmpty(result, "descr", 		 "Widget Description can not be null");
		ValidationUtils.rejectIfEmpty(result, "iconUrl", 	 "Icon URL can not be null");
		ValidationUtils.rejectIfEmpty(result, "displayName", "Display Name can not be null");				
		
		if ( !result.hasErrors() ) {
			mapToolConfigService.update(mapToolConfigBean);

			mapToolsDto.add(mapToolConfigBean);
			resp.setStatus("SUCCESS");
			resp.setResult(mapToolsDto);
		} else {
			resp.setStatus("FAIL");
			resp.setResult(result.getAllErrors());
		}

		return resp;
	}
	
	
	@RequestMapping(value = "/delete", method = RequestMethod.POST)
	@ResponseBody
	public EmpResponseBean delete(@RequestParam Long... ids) {
		MapToolConfigBean mapToolDto = null;
		EmpResponseBean resp = new EmpResponseBean();
		Boolean result = false;
		try {
			for (long curId : ids) {
				mapToolDto = new MapToolConfigBean();
				mapToolDto.setId(curId);
				result = mapToolConfigService.delete(mapToolDto);
			}
			
			if ( result ) {
				resp.setStatus("SUCCESS");
				resp.setResult(mapToolDto);
			} else {
				resp.setStatus("FAIL");
				resp.setResult(mapToolDto);
			}
		} catch (Exception e) {
			LOGGER.error("Delete operation on " + mapToolDto.getId() + " not successful");
		}
		
		return resp;
	}
	
	
	@RequestMapping(value = "/gridLoader", method = RequestMethod.GET)
	@ResponseBody
	public void getData(@Context HttpServletResponse response) {
		try {
			response.setContentType("text/html");
			response.setStatus(HttpServletResponse.SC_OK);
			response.getOutputStream().println(HttpServletResponse.SC_OK);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	@RequestMapping(value = "/descriptor", method = {RequestMethod.PUT, RequestMethod.POST})
	@ResponseBody
	public final void proxyAjaxCall( @RequestParam(required = false, value = "url", defaultValue = "") String url,
									 @RequestParam(required = false) boolean autoLaunch,
									 @RequestParam(required = false) boolean isHidden,
									 @Context HttpServletRequest request,
									 @Context HttpServletResponse response) throws IOException {

		response.setContentType("application/json");
		OutputStreamWriter writer = new OutputStreamWriter(
				response.getOutputStream());

		try {
			WidgetDataParser parser = new WidgetDataParser(url.toString());
			String widgetData = parser.getWidgetDataAsJsonString();
			mapToolConfigService.save(convertToMapToolBean(
					parser.getOwfDescriptorFromHtml(), autoLaunch, isHidden));

			writer.write(widgetData);
			writer.flush();
			writer.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	private MapToolConfigBean convertToMapToolBean(OwfDescriptorBean od, boolean autoLaunch, boolean isHidden) {
		MapToolConfigBean mtc = new MapToolConfigBean();
		
		mtc.setName(od.getDisplayName());
		mtc.setDisplayName(od.getDisplayName());
		mtc.setDescr(od.getDescription());
		mtc.setIconUrl(od.getImageUrlLarge());
		mtc.setAutoLaunch(autoLaunch);
		mtc.setHidden(isHidden);
		
		return mtc;
	}

}
